#ifndef FIBTHREAD_TYPES_H_
#define FIBTHREAD_TYPES_H_

#include "list.h"
#include <signal.h>

/* External data definitions */

extern long page_size;

/* Manifest constants */

#define QUANTA_MICRO_SECONDS					50000

#define THREAD_ID_COUNTER_MAX					0xFFFFFFFE

#define ALL_THREADS_BUCKET_CNT					((FIBTHREAD_THREADS_MAX) / 4)

#define FIBTHREAD_REAL_SCHED_PRIO_MAX			64

#define FIBTHREAD_SCHED_FIFO_PRIO_MIN			0
#define FIBTHREAD_SCHED_FIFO_PRIO_MAX			FIBTHREAD_REAL_SCHED_PRIO_MAX
#define FIBTHREAD_SCHED_RR_PRIO_MIN				0
#define FIBTHREAD_SCHED_RR_PRIO_MAX				FIBTHREAD_REAL_SCHED_PRIO_MAX

#define FIBTHREAD_SCHED_POLICY_DEFAULT			FIBTHREAD_SCHED_RR
#define FIBTHREAD_SCHED_PRIORITY_DEFAULT		32

#define FIBTHREAD_ATTR_INITIALIZED				0xFFFFDAED
#define FIBTHREAD_ATTR_DESTROYED				0xFFFFDEAD

#define FIBTHREAD_STACK_MIN						(page_size * 8)
#define FIBTHREAD_STACK_DEFAULT					(page_size * 64)

#define FIBTHREAD_GUARD_DEFAULT					(page_size * 2)

#define FIBTHREAD_MUTEX_STAT_INITIALIZED		0
#define FIBTHREAD_MUTEX_INITIALIZED				0xFFFFDAED
#define FIBTHREAD_MUTEX_DESTROYED				0xFFFFDEAD

/* Detach state attributes will be here */

#define FIBTHREAD_CREATE_JOINABLE				0
#define FIBTHREAD_CREATE_DETACHED				1

/* Type definitions */

typedef unsigned char u8_t;
typedef unsigned short u16_t;
typedef unsigned int u32_t;
typedef unsigned long u64_t;

typedef signed char i8_t;
typedef short i16_t;
typedef int i32_t;
typedef long i64_t;

typedef u8_t boolean;

#define true 1
#define false 0

typedef struct {
	doubly_node node;
	struct fibthread_struct *thread;
} sync_node_t;

typedef u32_t fibthread_t;

typedef struct {
	unsigned type:4;
} fibthread_mutexattr_t;

typedef struct {
	u32_t lock_count;
	struct fibthread_struct *owner;
	doubly_list wait_list;			/* Not NULL ended */
	fibthread_mutexattr_t attr;
	u32_t initialized;
} fibthread_mutex_t;


struct fibsched_param {
	i32_t sched_priority;
};

typedef struct {
	i32_t sched_policy;
	struct fibsched_param sched_param;
	i32_t detach_state;
	size_t stack_size;
	size_t guard_size;
	i32_t initialized;

	void *stack_addr;
} fibthread_attr_t;

/*
 * We will be allocating place here for register values
 * that are the snapshot of current thread
 *
 *  -------0000
 *	EIP
 *	-------
 *	EBP
 *	-------
 *	EBX
 *	-------
 *	ESI
 *	-------
 *	EDI
 *	-------
 *	ECX
 *	-------
 *	EDX
 *	-------
 *	FS
 *	-------FFFF
 *
 */

typedef struct fibthread_registers {
// 	#ifdef __x86_64
// 	#define NUM_REGISTERS		6 /* It is dummy for NOW Todo : Fix it*/
// 	#else
	void *eip;
	void *ebp;
	void *ebx;
	void *esi;
	void *edi;
	void *ecx;
	void *edx;
	void *fs;
// 	#endif
} fibthread_registers;

typedef struct fibthread_struct {
	void *bottom_stack;
	void *stack_addr;
	fibthread_registers registers;
	int thread_errno;

	fibthread_t id;
	fibthread_attr_t attr;
	short *stack_guard;
	/*
	 * "Geri dönüş" değeri. fibthread_exit, fibthread_join,
	 * vs. fonksiyonları da bu alandan sebepleniyor.
	 */
	void *return_value_ptr;
	void *(*start_routine)(void*);
	void *arg;
	struct fibthread_struct *join_thread;

	/* Signal (thread_specific) fields will be here */
	sigset_t thread_mask;
	sigset_t pending_signals;

	/** We simply have too much nodes... **/

	doubly_node all_threads;
	doubly_node zombie_node;
	doubly_node join_node; /* Threads that are waiting for others */
	singly_list detach_node; /* Detached items fall here */
	doubly_node queue_node;
} fibthread_struct;

/* External data declarations */

extern fibthread_struct *curr_thread;
extern u32_t thread_counter;
extern u32_t active_thread_counter;

extern doubly_list priority_queues[FIBTHREAD_REAL_SCHED_PRIO_MAX];
extern singly_list detached_threads; /* Threads that are finished and in detached state will be appended here */


#endif
